package com.yonyou.pmclouds.basecom.util;

import java.io.*;
import java.lang.reflect.Array;
import java.util.*;


/**
 * Object公共处理类
 * <p>
 * 基本工具类整体的优先级上，优先使用java内置的工具类，如：Arrays，Collecttions等
 * <br>
 * 然后是commons-langs中的工具类，时间相关优先使用joda-time
 * <br>代码中，避免出现Object的操作
 * <br>为什么优先使用开源的工具类，因为这些工具类相对问题，性能比较良好，
 * <br>而且后续维护者对开源工具类的熟悉程度相对会比内部的工具类要好
 * <br>尽可能减少非工程云特性相关的工具类
 * @author liaojia
 */
public class CommonObjUtil {


    /**
     * 初始化字符串
     *
     * @deprecated string 相关操作优先使用commons-lang3的StringUtils
     */
    @Deprecated
    public static String initStr(Object o) {
        return o == null ? "" : o.toString().trim();
    }


    /**
     * 初始化日期
     *
     * @param o
     * @return
     */
    public static Date initdate(Object o) {

        if (o == null || o.toString().length() == 0)
            return null;
        if (o instanceof Date)
            return (Date) o;
        else
            return new Date(o.toString());
    }


    /**
     * 方法描述：将dataStr转换成Integer
     *
     * @param dataStr
     * @return
     */
    public static Integer initInteger(Object dataStr) {
        return dataStr == null || dataStr.toString().trim().length() == 0 ? null : new Integer(dataStr.toString());
    }

    /**
     * 方法描述：初始化Integer，当obj为null时返回0，当obj不为null的时候返回Integer类型的obj
     *
     * @param object
     * @return
     */
    public static Integer initIntegerNotNull(Object object) {
        Integer value = initInteger(object);
        return CommonObjUtil.isEmpty(value) ? Integer.valueOf(0) : value;
    }


    /**
     * <p>
     * <li>判断对象是否为空</li>
     * <li>一般对象为null返回true</li>
     * <li>String对象为null或空字符串（不去空格）返回ture</li>
     * <li>集合,数组,Map为空，或没有元素，或元素值全部为空，返回ture</li>
     * </p>
     *
     * @param obj
     * @return
     * @deprecated 强烈不推荐这种大而全的判空类！ commentby mapeif
     */
    @Deprecated
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static boolean isEmpty(Object obj) {
        if (obj == null)
            return true;
        if (obj instanceof String) {
            return "".equals(((String) obj).trim());
        } else if (obj instanceof Map) {
            return isEmpty(((Map) obj).values());
        } else if (obj instanceof Enumeration) {
            Enumeration enumeration = (Enumeration) obj;
            while (enumeration.hasMoreElements()) {
                if (!isEmpty(enumeration.nextElement()))
                    return false;
            }
        } else if (obj instanceof Iterable) {
            if (obj instanceof List && obj instanceof RandomAccess) {
                List<Object> objList = (List) obj;
                for (int i = 0; i < objList.size(); i++) {
                    if (!isEmpty(objList.get(i)))
                        return false;
                }

            } else return isEmpty(((Iterable) obj).iterator());
        } else if (obj instanceof Iterator) {
            Iterator it = (Iterator) obj;
            while (it.hasNext()) {
                if (!isEmpty(it.next()))
                    return false;
            }
        } else if (obj instanceof Object[]) {
            Object[] objs = (Object[]) obj;
            for (Object elem : objs) {
                if (!isEmpty(elem))
                    return false;
            }
        } else if (obj instanceof int[]) {
            for (Object elem : (int[]) obj) {
                if (!isEmpty(elem))
                    return false;
            }
        } else {
            return false;
        }
        return true;
    }


    /**
     * 描述：利用序列化进行深复制
     * 作者：周圣城
     * 日期：2010-02-24  上午08:50:26
     *
     * @param oldObj
     * @return
     */
    public static Object copy(Object oldObj) {
        Object obj = null;
        try {
            // Write the object out to a byte array
            ByteArrayOutputStream bos = new ByteArrayOutputStream();


            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(oldObj);
            out.flush();
            out.close();

            // Retrieve an input stream from the byte array and read
            // a copy of the object back in.
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream in = new ObjectInputStream(bis);
            obj = in.readObject();
        } catch (IOException e) {
        } catch (ClassNotFoundException cnfe) {
        }
        return obj;
    }

    /**
     * @param value1
     * @param value2
     * @return
     * @description
     * @author
     * @datetime 2013-5-8 上午9:17:55
     */
    public static boolean equals(Object value1, Object value2) {
        return (value1 == null && value2 == null) || (value1 != null && value1.equals(value2));
    }


    @SuppressWarnings("unchecked")
    public static <E> E[] filterEmptyElements(E[] arr) {
        if (arr == null || arr.length == 0)
            return arr;
        List<E> l = new ArrayList<E>(arr.length);
        for (E e : arr) {
            if (CommonObjUtil.isEmpty(e))
                continue;
            l.add(e);
        }
        return l.toArray((E[]) Array.newInstance(arr[0].getClass(), 0));
    }

    /**
     * 数组合并，将多个同类型数组合并成一个数组
     *
     * @param clazz 数组元素类型
     * @param objs  对象数组
     * @return 与数组元素类型相同的对象数组
     */
    @SuppressWarnings("rawtypes")
    public static Object[] mergeArrays(Class clazz, Object[]... objs) {
        if (objs == null || objs.length == 0)
            return null;
        int len = 0;
        //计算合并后数组长度
        for (Object[] obj : objs)
            if (obj != null)
                len += obj.length;
        //创建合并后的数组对象
        Object[] mergeArray = (Object[]) Array.newInstance(clazz, len);
        int pos = 0;
        for (Object[] obj : objs) {
            if (obj != null) {
                //将每个数组对象复制到结果数组对象中
                System.arraycopy(obj, 0, mergeArray, pos, obj.length);
                pos = pos + obj.length;
            }
        }
        return mergeArray;
    }

    /**
     * @param <T>
     * @param elementData
     * @param size
     * @param a
     * @return T[]
     * @description 转换Object数组到指定类型的数组
     * @author zhangyun1
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] toArray(Object[] elementData, T[] a) {
        if (elementData == null) return null;
        int size = elementData.length;
        //1.如果指定类型的数组长度小于需要转换类型的数组长度
        if (a.length < size)
            //实例化转换类型后的数组
            a = (T[]) java.lang.reflect.Array.newInstance(a.getClass()
                    .getComponentType(), size);
        //2.复制原数组属性到转换后的数组
        System.arraycopy(elementData, 0, a, 0, size);
//		//3.新数组长度大于原数组长度,设置为空
//		if (a.length > size)
//			a[size] = null;
        return a;
    }


}
